/**
 * @file wsdl_service.cpp
 * @brief ONVIF WSDL文档服务实现
 * 
 * 本文件实现ONVIF协议的WSDL文档生成和处理功能
 * 支持Device Management、Media、PTZ等服务的WSDL文档
 */

#include "wsdl_service.h"
#include <sstream>
#include <algorithm>

namespace El {
namespace Onvif {

WSDLService::WSDLService(const std::string& baseUrl) 
    : baseUrl_(baseUrl) {
    InitializePathMapping();
}



void WSDLService::InitializePathMapping() {
    pathMapping_ = {
        {"/onvif/device_service?wsdl", WSDLType::Device},
        {"/onvif/media_service?wsdl", WSDLType::Media},
        {"/onvif/ptz_service?wsdl", WSDLType::PTZ},
        {"/onvif/imaging_service?wsdl", WSDLType::Imaging},
        {"/onvif/events_service?wsdl", WSDLType::Events},
        {"/onvif/analytics_service?wsdl", WSDLType::Analytics}
    };
}

std::string WSDLService::GetWSDL(WSDLType type) const {
    switch (type) {
        case WSDLType::Device:
            return GenerateDeviceWSDL();
        case WSDLType::Media:
            return GenerateMediaWSDL();
        case WSDLType::PTZ:
            return GeneratePTZWSDL();
        case WSDLType::Imaging:
            return GenerateImagingWSDL();
        case WSDLType::Events:
            return GenerateEventsWSDL();
        case WSDLType::Analytics:
            return GenerateAnalyticsWSDL();
        default:
            return "";
    }
}

std::string WSDLService::GetWSDLByPath(const std::string& path) const {
    auto it = pathMapping_.find(path);
    if (it != pathMapping_.end()) {
        return GetWSDL(it->second);
    }
    return "";
}

bool WSDLService::IsWSDLRequest(const std::string& path) const {
    return pathMapping_.find(path) != pathMapping_.end();
}

std::string WSDLService::GenerateWSDLHeader(const std::string& /* serviceName */, 
                                          const std::string& targetNamespace) const {
    std::ostringstream oss;
    oss << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        << "<definitions xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n"
        << "    xmlns:tns=\"" << targetNamespace << "\"\n"
        << "    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n"
        << "    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n"
        << "    xmlns:tt=\"http://www.onvif.org/ver10/schema\"\n"
        << "    targetNamespace=\"" << targetNamespace << "\"\n"
        << "    elementFormDefault=\"qualified\">\n\n";
    return oss.str();
}

std::string WSDLService::GenerateWSDLFooter() const {
    return "</definitions>\n";
}

std::string WSDLService::GenerateDeviceWSDL() const {
    std::ostringstream oss;
    
    // WSDL头部
    oss << GenerateWSDLHeader("DeviceService", "http://www.onvif.org/ver10/device/wsdl");
    
    // 类型定义
    oss << "  <types>\n"
        << "    <xs:schema targetNamespace=\"http://www.onvif.org/ver10/device/wsdl\">\n"
        << "      <xs:element name=\"GetDeviceInformation\">\n"
        << "        <xs:complexType><xs:sequence/></xs:complexType>\n"
        << "      </xs:element>\n"
        << "      <xs:element name=\"GetDeviceInformationResponse\">\n"
        << "        <xs:complexType>\n"
        << "          <xs:sequence>\n"
        << "            <xs:element name=\"Manufacturer\" type=\"xs:string\"/>\n"
        << "            <xs:element name=\"Model\" type=\"xs:string\"/>\n"
        << "            <xs:element name=\"FirmwareVersion\" type=\"xs:string\"/>\n"
        << "            <xs:element name=\"SerialNumber\" type=\"xs:string\"/>\n"
        << "            <xs:element name=\"HardwareId\" type=\"xs:string\"/>\n"
        << "          </xs:sequence>\n"
        << "        </xs:complexType>\n"
        << "      </xs:element>\n"
        << "    </xs:schema>\n"
        << "  </types>\n\n";
    
    // 消息定义
    oss << "  <message name=\"GetDeviceInformationRequest\">\n"
        << "    <part name=\"parameters\" element=\"tns:GetDeviceInformation\"/>\n"
        << "  </message>\n"
        << "  <message name=\"GetDeviceInformationResponse\">\n"
        << "    <part name=\"parameters\" element=\"tns:GetDeviceInformationResponse\"/>\n"
        << "  </message>\n\n";
    
    // 端口类型定义
    oss << "  <portType name=\"Device\">\n"
        << "    <operation name=\"GetDeviceInformation\">\n"
        << "      <input message=\"tns:GetDeviceInformationRequest\"/>\n"
        << "      <output message=\"tns:GetDeviceInformationResponse\"/>\n"
        << "    </operation>\n"
        << "  </portType>\n\n";
    
    // 绑定定义
    oss << "  <binding name=\"DeviceBinding\" type=\"tns:Device\">\n"
        << "    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n"
        << "    <operation name=\"GetDeviceInformation\">\n"
        << "      <soap:operation soapAction=\"http://www.onvif.org/ver10/device/wsdl/GetDeviceInformation\"/>\n"
        << "      <input><soap:body use=\"literal\"/></input>\n"
        << "      <output><soap:body use=\"literal\"/></output>\n"
        << "    </operation>\n"
        << "  </binding>\n\n";
    
    // 服务定义
    oss << "  <service name=\"DeviceService\">\n"
        << "    <port name=\"DevicePort\" binding=\"tns:DeviceBinding\">\n"
        << "      <soap:address location=\"" << EscapeXml(baseUrl_) << "/onvif/device_service\"/>\n"
        << "    </port>\n"
        << "  </service>\n\n";
    
    // WSDL尾部
    oss << GenerateWSDLFooter();
    
    return oss.str();
}

std::string WSDLService::GenerateMediaWSDL() const {
    std::ostringstream oss;
    oss << GenerateWSDLHeader("MediaService", "http://www.onvif.org/ver10/media/wsdl");
    oss << "  <!-- Media Service WSDL - Future Implementation -->\n";
    oss << GenerateWSDLFooter();
    return oss.str();
}

std::string WSDLService::GeneratePTZWSDL() const {
    std::ostringstream oss;
    oss << GenerateWSDLHeader("PTZService", "http://www.onvif.org/ver20/ptz/wsdl");
    oss << "  <!-- PTZ Service WSDL - Future Implementation -->\n";
    oss << GenerateWSDLFooter();
    return oss.str();
}

std::string WSDLService::GenerateImagingWSDL() const {
    std::ostringstream oss;
    oss << GenerateWSDLHeader("ImagingService", "http://www.onvif.org/ver20/imaging/wsdl");
    oss << "  <!-- Imaging Service WSDL - Future Implementation -->\n";
    oss << GenerateWSDLFooter();
    return oss.str();
}

std::string WSDLService::GenerateEventsWSDL() const {
    std::ostringstream oss;
    oss << GenerateWSDLHeader("EventsService", "http://www.onvif.org/ver10/events/wsdl");
    oss << "  <!-- Events Service WSDL - Future Implementation -->\n";
    oss << GenerateWSDLFooter();
    return oss.str();
}

std::string WSDLService::GenerateAnalyticsWSDL() const {
    std::ostringstream oss;
    oss << GenerateWSDLHeader("AnalyticsService", "http://www.onvif.org/ver20/analytics/wsdl");
    oss << "  <!-- Analytics Service WSDL - Future Implementation -->\n";
    oss << GenerateWSDLFooter();
    return oss.str();
}

std::string WSDLService::EscapeXml(const std::string& input) const {
    std::string escaped = input;
    
    // 替换XML特殊字符
    std::string::size_type pos = 0;
    while ((pos = escaped.find('&', pos)) != std::string::npos) {
        escaped.replace(pos, 1, "&amp;");
        pos += 5;
    }
    
    pos = 0;
    while ((pos = escaped.find('<', pos)) != std::string::npos) {
        escaped.replace(pos, 1, "&lt;");
        pos += 4;
    }
    
    pos = 0;
    while ((pos = escaped.find('>', pos)) != std::string::npos) {
        escaped.replace(pos, 1, "&gt;");
        pos += 4;
    }
    
    pos = 0;
    while ((pos = escaped.find('"', pos)) != std::string::npos) {
        escaped.replace(pos, 1, "&quot;");
        pos += 6;
    }
    
    pos = 0;
    while ((pos = escaped.find('\'', pos)) != std::string::npos) {
        escaped.replace(pos, 1, "&apos;");
        pos += 6;
    }
    
    return escaped;
}

} // namespace Onvif
} // namespace El 